package com.jilefojing.dao.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

import com.jilefojing.beans.enums.ItemTypeEnumForSource;
import com.jilefojing.beans.enums.forcomment.StatusEnumForComment;
import com.jilefojing.beans.pojos.Comment;
import com.jilefojing.beans.query.CommentQuery;
import com.jilefojing.beans.vo.Pagination;
import com.jilefojing.dao.ICommentDao;
import com.jilefojing.dao.base.impl.BaseDao;
import com.jilefojing.dao.mapper.ICommentMapper;
import com.jilefojing.util.Detect;

/**
 * 
 * @author 作者 jgshun
 * @date 创建时间 2016年07月21日 15时40分56秒
 */
@Repository
public class CommentDao extends BaseDao<Comment> implements ICommentDao {
	@Autowired
	private ICommentMapper commentMapper;

	@Override
	public Pagination<Comment> getPagination(CommentQuery commentQuery, Pagination<Comment> pagination) {
		Example example = new Example(Comment.class);
		Criteria criteria = example.createCriteria();
		if (Detect.notEmpty(commentQuery.getIds())) {
			criteria.andIn(Comment.FIELD_ID, commentQuery.getIds());
		}

		if (Detect.notEmpty(commentQuery.getItemTypes()) && Detect.notEmpty(commentQuery.getItemIds())) {
			List<Short> itemTypeCodes = new ArrayList<Short>();
			for (ItemTypeEnumForSource _itemType : commentQuery.getItemTypes()) {
				itemTypeCodes.add(_itemType.getCode());
			}
			String allItemIdAndTypeOrTopItemAndType = this.getAllItemIdAndTypeOrTopItemAndTypeCondition(itemTypeCodes, commentQuery.getItemIds());

			criteria.andCondition(allItemIdAndTypeOrTopItemAndType);
		} else {
			if (Detect.notEmpty(commentQuery.getItemTypes())) {
				List<Short> itemTypeCodes = new ArrayList<Short>();
				for (ItemTypeEnumForSource _itemType : commentQuery.getItemTypes()) {
					itemTypeCodes.add(_itemType.getCode());
				}
				String allItemTypeCondition = this.getAllItemTypesCondition(itemTypeCodes);
				criteria.andCondition(allItemTypeCondition);
				// criteria.andIn(Comment.FIELD_ITEMTYPE, itemTypeCodes);
			}

			if (Detect.notEmpty(commentQuery.getItemIds())) {
				String allItemIdCondition = this.getAllItemIdsCondition(commentQuery.getItemIds());
				criteria.andCondition(allItemIdCondition);
				// criteria.andIn(Comment.FIELD_ITEMID,
				// commentQuery.getItemIds());
			}

		}

		if (Detect.notEmpty(commentQuery.getUserIds())) {
			criteria.andIn(Comment.FIELD_USERID, commentQuery.getUserIds());
		}

		if (Detect.notEmpty(commentQuery.getLike_content())) {
			criteria.andLike(Comment.FIELD_CONTENT, "%" + commentQuery.getLike_content() + "%");
		}

		if (Detect.notEmpty(commentQuery.getContent())) {
			criteria.andEqualTo(Comment.FIELD_CONTENT, commentQuery.getContent());
		}

		if (Detect.notEmpty(commentQuery.getStatuses())) {
			List<Short> statusCodes = new ArrayList<Short>();
			for (StatusEnumForComment _status : commentQuery.getStatuses()) {
				statusCodes.add(_status.getCode());
			}
			criteria.andIn(Comment.FIELD_STATUS, statusCodes);
		}

		if (commentQuery.getEqualCreateTime() != null) {
			criteria.andEqualTo(Comment.FIELD_CREATETIME, commentQuery.getEqualCreateTime());
		}

		if (commentQuery.getEqualAndBeforCreateTime() != null) {
			criteria.andGreaterThanOrEqualTo(Comment.FIELD_CREATETIME, commentQuery.getEqualAndBeforCreateTime());
		}

		if (commentQuery.getEqualAndAfterCreateTime() != null) {
			criteria.andLessThanOrEqualTo(Comment.FIELD_CREATETIME, commentQuery.getEqualAndAfterCreateTime());
		}

		if (commentQuery.getBeforCreateTime() != null) {
			criteria.andGreaterThan(Comment.FIELD_CREATETIME, commentQuery.getBeforCreateTime());
		}

		if (commentQuery.getAfterCreateTime() != null) {
			criteria.andLessThan(Comment.FIELD_CREATETIME, commentQuery.getAfterCreateTime());
		}

		if (commentQuery.getEqualUpdateTime() != null) {
			criteria.andEqualTo(Comment.FIELD_UPDATETIME, commentQuery.getEqualUpdateTime());
		}

		if (commentQuery.getEqualAndBeforUpdateTime() != null) {
			criteria.andGreaterThanOrEqualTo(Comment.FIELD_UPDATETIME, commentQuery.getEqualAndBeforUpdateTime());
		}

		if (commentQuery.getEqualAndAfterUpdateTime() != null) {
			criteria.andLessThanOrEqualTo(Comment.FIELD_UPDATETIME, commentQuery.getEqualAndAfterUpdateTime());
		}

		if (commentQuery.getBeforUpdateTime() != null) {
			criteria.andGreaterThan(Comment.FIELD_UPDATETIME, commentQuery.getBeforUpdateTime());
		}

		if (commentQuery.getAfterUpdateTime() != null) {
			criteria.andLessThan(Comment.FIELD_UPDATETIME, commentQuery.getAfterUpdateTime());
		}

		if (Detect.notEmpty(commentQuery.getTopCommentIds())) {
			criteria.andIn(Comment.FIELD_TOPCOMMENTID, commentQuery.getTopCommentIds());
		}

		if (Detect.notEmpty(pagination.getOrders())) {
			example.setOrderByClause(pagination.getOrdersToStr());
		}

		return super.getPagination(pagination, example);
	}

	private String getAllItemIdAndTypeOrTopItemAndTypeCondition(List<Short> itemTypeCodes, List<Long> itemIds) {
		// ( (itemId in (1,2,3) and itemType in (1,2,3)) or ( topItemId in
		// (1,2,3) and topItemType in (1,2,3,4) ) )

		StringBuilder valBud = new StringBuilder();
		valBud.append(" ( ( ").append(Comment.COLUMN_ITEM_ID).append(" in ( ");
		for (int i = 0; i < itemIds.size(); i++) {
			long itemId = itemIds.get(i);
			valBud.append(itemId);
			if (i < itemIds.size() - 1) {
				valBud.append(" , ");
			}
		}
		valBud.append(" ) and ").append(Comment.COLUMN_ITEM_TYPE).append(" in ( ");
		for (int i = 0; i < itemTypeCodes.size(); i++) {
			short itemTypeCode = itemTypeCodes.get(i);
			valBud.append(itemTypeCode);
			if (i < itemTypeCodes.size() - 1) {
				valBud.append(" , ");
			}
		}
		valBud.append(" ) ) or ( ").append(Comment.COLUMN_TOP_ITEM_ID).append(" in ( ");
		for (int i = 0; i < itemIds.size(); i++) {
			long itemId = itemIds.get(i);
			valBud.append(itemId);
			if (i < itemIds.size() - 1) {
				valBud.append(" , ");
			}
		}
		valBud.append(" ) and ").append(Comment.COLUMN_TOP_ITEM_TYPE).append(" in ( ");
		for (int i = 0; i < itemTypeCodes.size(); i++) {
			short itemTypeCode = itemTypeCodes.get(i);
			valBud.append(itemTypeCode);
			if (i < itemTypeCodes.size() - 1) {
				valBud.append(" , ");
			}
		}
		valBud.append(" ) ) ) ");

		return valBud.toString();
	}

	private String getAllItemIdsCondition(List<Long> itemIds) {
		StringBuilder valBud = new StringBuilder();
		valBud.append(" ( ");
		for (int i = 0; i < itemIds.size(); i++) {
			long itemId = itemIds.get(i);
			valBud.append(itemId);
			if (i != itemIds.size() - 1) {
				valBud.append(" , ");
			}
		}
		valBud.append(" ) ");

		StringBuilder conditionBud = new StringBuilder();
		conditionBud.append(" ( ").append(Comment.COLUMN_ITEM_ID).append(" in ").append(valBud.toString()).append(" or ").append(Comment.COLUMN_TOP_ITEM_ID).append(" in ").append(valBud.toString())
				.append(" ) ");

		return conditionBud.toString();
	}

	private String getAllItemTypesCondition(List<Short> itemTypeCodes) {
		StringBuilder valBud = new StringBuilder();
		valBud.append(" ( ");
		for (int i = 0; i < itemTypeCodes.size(); i++) {
			short itemTypeCode = itemTypeCodes.get(i);
			valBud.append(itemTypeCode);
			if (i != itemTypeCodes.size() - 1) {
				valBud.append(" , ");
			}
		}
		valBud.append(" ) ");

		StringBuilder conditionBud = new StringBuilder();
		conditionBud.append(" ( ").append(Comment.COLUMN_ITEM_TYPE).append(" in ").append(valBud.toString()).append(" or ").append(Comment.COLUMN_TOP_ITEM_TYPE).append(" in ")
				.append(valBud.toString()).append(" ) ");

		return conditionBud.toString();
	}

	@Override
	public List<Comment> getListByIds(List<Long> ids) {
		Example example = new Example(Comment.class);
		example.createCriteria().andIn(Comment.FIELD_ID, ids);
		return super.getListByExample(example);
	}

	@Override
	public List<Map<String, Integer>> countChildCommentsForTopByTopCommentIds(List<Long> topCommentIds, List<StatusEnumForComment> statuses) {
		return commentMapper.countChildCommentsForTopByTopCommentIds(topCommentIds, statuses);
	}
}
